/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.espier.t9keyboard;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;


import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.AsyncQueryHandler;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabaseCorruptException;
import android.database.sqlite.SQLiteDiskIOException;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteFullException;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.AudioManager;
import android.media.ToneGenerator;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.Vibrator;
import android.provider.Contacts.People;
import android.provider.Contacts.Phones;
import android.provider.Contacts.PhonesColumns;
import android.provider.ContactsContract.Contacts;
import android.provider.ContactsContract.Data;
import android.provider.Settings;
import android.telephony.PhoneNumberFormattingTextWatcher;
import android.telephony.PhoneNumberUtils;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.text.Editable;
import android.text.Html;
import android.text.SpannableStringBuilder;
import android.text.TextUtils;
import android.text.TextWatcher;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.View.OnFocusChangeListener;
import android.view.ViewConfiguration;
import android.view.ViewGroup;
import android.view.animation.TranslateAnimation;
import android.view.inputmethod.InputMethodManager;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.ResourceCursorAdapter;
import android.widget.SlidingDrawer;
import android.widget.TextView;
import android.widget.Toast;


/**
 * Dialer activity that displays the typical twelve key interface.
 */
public class CopyOfTwelveKeyDialer1 extends Activity implements View.OnClickListener,
        View.OnLongClickListener, View.OnKeyListener,
        TextWatcher {

    private static final String TAG = "TwelveKeyDialer";
    
    private static final int STOP_TONE = 1;

    /** The length of DTMF tones in milliseconds */
    private static final int TONE_LENGTH_MS = 150;
    
    /** The DTMF tone volume relative to other sounds in the stream */
    private static final int TONE_RELATIVE_VOLUME = 80;

    /** Stream type used to play the DTMF tones off call, and mapped to the volume control keys */
    private static final int DIAL_TONE_STREAM_TYPE = AudioManager.STREAM_MUSIC;

    /** Play the vibrate pattern only once. */
    private static final int VIBRATE_NO_REPEAT = -1;
    
    
    public static final int REQUEST_SEND_CALL=100;
    private boolean isActivityRequestSendCall;
    private Intent mRequestIntent;

    private EditText mDigits;
    private EditText mDigitsShow;
    private View mDelete;
//    private MenuItem mAddToContactMenuItem;
    private ToneGenerator mToneGenerator;
    private Object mToneGeneratorLock = new Object();
    private View mDialpad;
//    private ListView mDialpadChooser;
    private DialpadChooserAdapter mDialpadChooserAdapter;
    
    private long mStarKeyPressedTime = 0;

    // determines if we want to playback local DTMF tones.
    private boolean mDTMFToneEnabled;

    // Vibration (haptic feedback) for dialer key presses.
    private Vibrator mVibrator;
    private boolean mVibrateOn;
    private long[] mVibratePattern;
    
    private Button mBtnCall1;
    private Button mBtnCall2;
    private Button mBtnEmergencyCall;
    private static final  String  TELEPHONY_SERVICE_TWO = "phone.1";


    /** Identifier for the "Add Call" intent extra. */
    static final String ADD_CALL_MODE_KEY = "add_call_mode";

    /**
     * Identifier for intent extra for sending an empty Flash message for
     * CDMA networks. This message is used by the network to simulate a
     * press/depress of the "hookswitch" of a landline phone. Aka "empty flash".
     *
     * TODO: Using an intent extra to tell the phone to send this flash is a
     * temporary measure. To be replaced with an ITelephony call in the future.
     * TODO: Keep in sync with the string defined in OutgoingCallBroadcaster.java
     * in Phone app until this is replaced with the ITelephony API.
     */
    static final String EXTRA_SEND_EMPTY_FLASH
            = "com.android.phone.extra.SEND_EMPTY_FLASH";

    /** Indicates if we are opening this dialer to add a call from the InCallScreen. */
    private boolean mIsAddCallMode;
    
    private SlidingDrawer mDialerDrawer;
    private ImageButton mShowHideKeypad;
    
    private ListView mContactsListView;
    private ContactsAdapter mAdapter;
    private QueryHandler mQueryHandler;
    private MyContactAdapter mContactAdapter;
    private List<ContactPerson> mContactList;
    private List<MyCallLog> mCallLogList;
    
    private int mAsyncTaskNumber;
    private boolean notShowOrHideDigitsView;
    
    private String mSelectedNumber;
    private boolean isDelNumber = false;
    
    private static final int QUERY_TOKEN = 53;
    public static final Uri PHONES_AND_CALLLOG_CONTENT_URI =
        Uri.parse("content://com.android.contacts/phones_and_calllog");
    
    public static final Uri CONTACTS_CONTENT_URI=Uri.parse("content://com.android.contacts/contacts");

    
    /** The projection to use when querying the call log table */
    static final String[] PHONES_AND_CALLLOG_PROJECTION = new String[] {
    	    "_id",
    	    "number",
    	    Contacts.DISPLAY_NAME,
    	    "type",
    	    "label",
    	    "dialpad_number_short",
    	    "dialpad_number_full",
    	    "dialpad_index_short",
    	    "dialpad_index_full",
    	    Contacts.PHOTO_ID,
    	    "people_id",
    	    "data_id"
    };
    
    static final int ID_COLUMN_INDEX = 0;
    static final int NUMBER_COLUMN_INDEX = 1;
    static final int CALLER_NAME_COLUMN_INDEX = 2;
    static final int CALLER_NUMBERTYPE_COLUMN_INDEX = 3;
    static final int CALLER_NUMBERLABEL_COLUMN_INDEX = 4;
    static final int CALLER_NUMBER_SHORT_INDEX = 5;
    static final int CALLER_NUMBER_FULL_INDEX = 6;
    static final int CALLER_NUMBER_INDEX_SHORT_INDEX = 7;
    static final int CALLER_NUMBER_INDEX_FULL_INDEX = 8;
    static final int CALLER_PHOTO_INDEX = 9;
    static final int CALLER_PEOPLE_ID = 10;
    static final int CALLER_DATA_ID = 11;
    
    static final int DOUBLE_CLICK_TAP = 1000;
    
    static final String EXTRA_PHONE_ID = "phoneid";
    boolean mIsDsds = false;
    
    private LinearLayout mLlShowDailpad;
    private ImageButton mIbtnShowdailpad;
    
    private LinearLayout mContactsListViewLl;
    private LinearLayout mShowDigitsLl;
    
    private LinearLayout mCreateContactsLl;
    private ImageView mNoDataIv;
    private RelativeLayout mCreateContactsItemRl;
    private RelativeLayout mAddToExistingContactItemRl;
    
//    private MenuWindow mCreateContactMenuWindow;
    
    private final int NO_CALLLOG_AND_CONTACTS = 100;
    private final int HAVE_CALLLOG_AND_CONTACTS = 101;
    private Handler mHandler=new Handler(){
    	public void handleMessage(Message msg) {
    		switch (msg.what) {
			case NO_CALLLOG_AND_CONTACTS:
				mContactsListView.setVisibility(View.GONE);
				mCreateContactsLl.setVisibility(View.VISIBLE);
				if(mDigits.getText().toString().length()>3){
					mCreateContactsItemRl.setVisibility(View.VISIBLE);
					mAddToExistingContactItemRl.setVisibility(View.VISIBLE);
					mNoDataIv.setVisibility(View.GONE);
				}else{
					mCreateContactsItemRl.setVisibility(View.GONE);
					mAddToExistingContactItemRl.setVisibility(View.GONE);
					mNoDataIv.setVisibility(View.VISIBLE);
				}
				break;
			case HAVE_CALLLOG_AND_CONTACTS:
				mContactsListView.setVisibility(View.VISIBLE);
				mCreateContactsLl.setVisibility(View.GONE);
				break;
			default:
				break;
			}
    	};
    };
    
    public static final class ContactsListItemViews {
        TextView line1View;
        TextView labelView;
        TextView numberView;
        ImageView operateButton;
        ImageView photoView;
    }
    
    public static final class ContactsListViewItemViews {
    	ImageView photoView;
        TextView nameView;
        TextView numberView;
        TextView addressView;
    }
    
    OnScrollListener listViewOnScrollListener=new OnScrollListener() {
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
		}
		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,
				int visibleItemCount, int totalItemCount) {
			
    	    mDialerDrawer.close();
    	    mLlShowDailpad.setVisibility(View.VISIBLE);
    	    view.clearFocus();
		}
		
	};
	
    
    OnItemClickListener mContactsListClickListener = new OnItemClickListener() {

        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            
        	if(!(view.getTag() instanceof ContactsListViewItemViews)){
        		return;
        	}
            ContactsListViewItemViews views=(ContactsListViewItemViews) view.getTag();
            TextView  tvName=views.nameView;
            TextView tvNumber=views.numberView;
            TextView tvAddress=views.addressView;
            ImageView ivPhotoView=views.photoView;
            
            String tel = tvNumber.getText().toString();
            boolean isContact =false;
            if(tvAddress.getTag()!=null){
            	isContact= ((Boolean) tvAddress.getTag()).booleanValue();
            }
           
            Log.v(TAG, " isContact is >>>" + isContact);
            if(!isContact){
            	tel=tvAddress.getText().toString();
            }
            
            notShowOrHideDigitsView=true;
            mDigits.getText().clear();
            analogKeyPressed(tel);
       	    mLlShowDailpad.setVisibility(View.GONE);
    	    mDialerDrawer.open();
    	    //mDialerDrawer.animateToggle();
        }
        
    };
    
//    OnCreateContextMenuListener mContactsListContextMenuListener = new OnCreateContextMenuListener() {
//
//        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfoIn) {
//            AdapterView.AdapterContextMenuInfo menuInfo;
//            try {
//                 menuInfo = (AdapterView.AdapterContextMenuInfo) menuInfoIn;
//            } catch (ClassCastException e) {
//                Log.e(TAG, "bad menuInfoIn", e);
//                return;
//            }
//
//            Cursor c = (Cursor) mAdapter.getItem(menuInfo.position);
//            
//            int id = c.getInt(ID_COLUMN_INDEX);
//            String number = c.getString(NUMBER_COLUMN_INDEX);
//            String formattedNumber = formatPhoneNumber(number);
//            String callerName = c.getString(CALLER_NAME_COLUMN_INDEX);
//            int callerNumberType = c.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
//            String callerNumberLabel = c.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
//            int peopleId = c.getInt(CALLER_PEOPLE_ID);
//            
//            String voiceMailNumber = ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE))
//            .getVoiceMailNumber();
//            
//            Uri numberUri = null;
//            boolean isVoicemail = false;
//            if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
//                number = getString(R.string.unknown);
//            } else if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
//                number = getString(R.string.private_num);
//            } else if (number.equals(CallerInfo.PAYPHONE_NUMBER)) {
//                number = getString(R.string.payphone);
//            } else if (number.equals(voiceMailNumber)) {
//                number = getString(R.string.voicemail);
//                numberUri = Uri.parse("voicemail:x");
//                isVoicemail = true;
//            } else {
//                number = PhoneNumberUtils.stripSeparators(number);
//                numberUri = Uri.fromParts("tel", number, null);
//            }
//
//            boolean isCalllog = id%2 == 0;
//            if (!TextUtils.isEmpty(callerName)) {
//                menu.setHeaderTitle(callerName);
//            } else{
//                menu.setHeaderTitle(number);
//            }
//
//            if (numberUri != null) {
//                Intent intent = new Intent(Intent.ACTION_DIAL, numberUri);
//                Intent intentContacts = new Intent("com.android.contacts.action.SHOW_OR_CREATE_CONTACT", numberUri);
//                menu.add(0, 0, 0, getResources().getString(R.string.recentCalls_callNumber, number))
//                        .setIntent(intent);
//
//                if (!isCalllog) {
//                	Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, peopleId);
//                    menu.add(0, 0, 0, R.string.menu_viewContact).setIntent(new Intent(Intent.ACTION_VIEW, contactUri));
//                } else if(!isVoicemail) {
//                    menu.add(0, 0, 0, R.string.recentCalls_addToContact).setIntent(intentContacts);
//                }
//            }
//
//            if (numberUri != null && !isVoicemail) {
//                menu.add(0, 0, 0, R.string.recentCalls_editNumberBeforeCall)
//                        .setIntent(new Intent(Intent.ACTION_DIAL, numberUri));
//                menu.add(0, 0, 0, R.string.menu_sendTextMessage)
//                        .setIntent(new Intent(Intent.ACTION_SENDTO,
//                                Uri.fromParts("sms", number, null)));
//            }
//            
////            menu.add(0, MENU_ITEM_DELETE, 0, R.string.recentCalls_removeFromRecentList);
//            
//        }
//    
//    };
    
    
    OnItemSelectedListener mContactsSelectedListener = new OnItemSelectedListener() {

        public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//            ContactsListItemViews views = (ContactsListItemViews)view.getTag();
//            if(!TextUtils.isEmpty(views.numberView.getText())){
//                mSelectedNumber = views.numberView.getText().toString();
//            }else{
//                mSelectedNumber = views.line1View.getText().toString();
//            }
//            
//            if(mDialerDrawer.isOpened()){
////                mShowHideKeypad.setImageDrawable(getResources().getDrawable(R.drawable.btn_display_keypad));
//                //mDialerDrawer.animateToggle();
//                //mDialerDrawer.setVisibility(View.GONE);
//            }
            
        }

        public void onNothingSelected(AdapterView<?> parent) {

        }
        
    };

    PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
            /**
             * Listen for phone state changes so that we can take down the
             * "dialpad chooser" if the phone becomes idle while the
             * chooser UI is visible.
             */
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                // Log.i(TAG, "PhoneStateListener.onCallStateChanged: "
                //       + state + ", '" + incomingNumber + "'");
//                if ((state == TelephonyManager.CALL_STATE_IDLE) && dialpadChooserVisible()) {
//                    // Log.i(TAG, "Call ended with dialpad chooser visible!  Taking it down...");
//                    // Note there's a race condition in the UI here: the
//                    // dialpad chooser could conceivably disappear (on its
//                    // own) at the exact moment the user was trying to select
//                    // one of the choices, which would be confusing.  (But at
//                    // least that's better than leaving the dialpad chooser
//                    // onscreen, but useless...)
//                    showDialpadChooser(false);
//                }
            }
        };

    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        // Do nothing
    }

    public void onTextChanged(CharSequence input, int start, int before, int changeCount) {
        // Do nothing
        // DTMF Tones do not need to be played here any longer - 
        // the DTMF dialer handles that functionality now.
    	String curString = input.toString();
    	curString = curString.replace(',', 'p');
    	curString = curString.replace(';', 'w');
//    	float stringWidth = mDigitsShow.getPaint().measureText(curString);
//    	Log.d(TAG, "before onTextChanged curString: " + curString );
//    	Log.d(TAG, "before change mDigitsShow.getWidth() : " + mDigitsShow.getWidth() );
//		Log.d(TAG, "before change mDigitsShow.getPaint().measureText(curString) : " + mDigitsShow.getPaint().measureText(curString) );
//    	Log.d(TAG, "before change mDigitsShow.getTextSize() the size is : " + mDigitsShow.getTextSize() );
//    	if (stringWidth > mDigitsShow.getMeasuredWidth()  && mDigitsShow.getTextSize() > 35) {
//    		while(true){
//    			Log.d(TAG, "break,and the size is : " + mDigitsShow.getTextSize() );
//				Log.d(TAG, "mDigitsShow.getWidth() : " + mDigitsShow.getWidth() );
//    			mDigitsShow.setTextSize(mDigitsShow.getTextSize()-1);
//    			Log.d(TAG, "size sub two");
//    			if(mDigitsShow.getPaint().measureText(curString) <=  mDigitsShow.getWidth() ) {
//    				Log.d(TAG, "break,and the size is : " + mDigitsShow.getTextSize() );
//    				Log.d(TAG, "mDigitsShow.getWidth() : " + mDigitsShow.getWidth() );
//    				Log.d(TAG, "mDigitsShow.getPaint().measureText(curString) : " + mDigitsShow.getPaint().measureText(curString) );
//    				break;
//    			}
//    		}
//    	}
    	
//        if (isDelNumber && stringWidth < mDigitsShow.getWidth()  && mDigitsShow.getTextSize() < 25) {
//    		while(true){
//    			TextPaint tp = new TextPaint();
//			float old_size = mDigitsShow.getTextSize();
//    			tp.setTextSize(old_size + 1);
//    			Log.d(TAG, "old_size is >>>"+old_size+",mDigitsShow.getTextSize is >>> " + mDigitsShow.getTextSize());				
//    			Log.d(TAG, "tp.setTextSize is >>> " + tp.getTextSize());
//    			Log.d(TAG, "tp.measureText(curString) is >>> " + tp.measureText(curString));
//    			if (tp.measureText(curString) > mDigitsShow.getWidth()) {
//    				Log.d(TAG, "tp break;");
//    				break;
//    			}
//    			if (mDigitsShow.getTextSize() > 25 ) {
//    				break;
//    			}
//    			Log.d(TAG, "size add two,mDigitsShow.getTextSize is >>>"+mDigitsShow.getTextSize());
//			int i =1;
//			while (old_size >= mDigitsShow.getTextSize())
//			{
//    				mDigitsShow.setTextSize(old_size+ i++);
//				Log.d(TAG, "2 size add two,mDigitsShow.getTextSize is >>>"+mDigitsShow.getTextSize());
//			}
//    		}
//    		isDelNumber = false;
//    	}
    }

    public void afterTextChanged(Editable input) {
//        if (SpecialCharSequenceMgr.handleChars(this, input.toString(), mDigits)) {
//            // A special sequence was entered, clear the digits
//            mDigits.getText().clear();
//            Log.d(TAG, "afterTextChanged SpecialCharSequenceMgr.handleChars   mDigits.getText().clear();");
//        }
        
        String text = mDigits.getText().toString();
        Log.d(TAG, "++++++++++++++++++++++++++======mDigits text:"+text);
        String textToShow = "";
        text = text.replace(',', 'p');
        text = text.replace(';', 'w');
        textToShow = text;
        mDigitsShow.getText().clear();
//        if (mDigitsShow.getPaint().measureText(text) > mDigitsShow.getWidth()) {
//        	if (text.length()-22 > 0) {
//        		textToShow = text.substring(text.length()-22);
//        		textToShow = "..." + textToShow;
//        		Log.d(TAG, " mDigitsShow.getPaint().measureText(text) > mDigitsShow.getWidth()");
//        	}
//        }else {
//        	textToShow = text;
//        }
        textToShow = text;
        mDigitsShow.getText().append(textToShow);

        setDigitsShowOrHideWithAnima();
        startQuery();
        
        // Set the proper background for the dial input area
//        if (mDigits.length() != 0) {
//            mDigits.setCompoundDrawablesWithIntrinsicBounds(
//                    getResources().getDrawable(R.drawable.ic_dial_number), null, null, null);
//        } else {
//            mDigits.setCompoundDrawablesWithIntrinsicBounds(null, null, null, null);
//        }
    }

    @Override
    protected void onCreate(Bundle icicle) {
        super.onCreate(icicle);
	    Log.w(TAG, "onCreate :mIsDsds= " + mIsDsds+",layout id="+getContentViewResource());
        // Set the content view
        setContentView(getContentViewResource());

        // Load up the resources for the text field and delete button
        Resources r = getResources();
        //mDigitsBackground.setDither(true);
        //mDigitsEmptyBackground.setDither(true);
        //mDeleteBackground.setDither(true);
        //mDeleteEmptyBackground.setDither(true);

        mShowDigitsLl=(LinearLayout)findViewById(R.id.showDigitsLl);
        mDigits = (EditText) findViewById(R.id.digits);
        mDigitsShow = (EditText) findViewById(R.id.digitsShow);
	    Log.w(TAG, "onCreate :mDigits= " + mDigits+",mDigitsShow="+mDigitsShow);
//        mDigits.setKeyListener(DialerKeyListener.getInstance());
//        mDigitsShow.setOnClickListener(this);
//        mDigitsShow.setOnKeyListener(this);
//        mDigitsShow.setOnLongClickListener(this);
//        maybeAddNumberFormatting();

        // Check for the presence of the keypad
        View view = findViewById(R.id.one);
        if (view != null) {
            setupKeypad();
        }

        view = findViewById(R.id.backspace);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        mDelete = view;
        
        mLlShowDailpad=(LinearLayout) findViewById(R.id.showDialPadll);
        mIbtnShowdailpad=(ImageButton) findViewById(R.id.showDialPadBtn);
        mIbtnShowdailpad.setOnClickListener(this);
               
        mDialerDrawer = (SlidingDrawer) findViewById(R.id.dialer_container);
        
        mDialpad = (View) findViewById(R.id.dialpad);  // This is null in landscape mode

        // Set up the "dialpad chooser" UI; see showDialpadChooser().
//        mDialpadChooser = (ListView) findViewById(R.id.dialpadChooser);
//        mDialpadChooser.setOnItemClickListener(this);
        
        mCreateContactsLl=(LinearLayout) findViewById(R.id.createContactsLl);
        mNoDataIv=(ImageView) findViewById(R.id.noDataIv);
        mCreateContactsItemRl=(RelativeLayout) findViewById(R.id.createContactsItemRl);
        mCreateContactsItemRl.setOnClickListener(this);
        mAddToExistingContactItemRl=(RelativeLayout) findViewById(R.id.addToExistingContactItemRl);
        mAddToExistingContactItemRl.setOnClickListener(this);

        mAdapter = new ContactsAdapter();
        mContactAdapter=new MyContactAdapter();
        
        mContactsListViewLl=(LinearLayout) findViewById(R.id.contactsListLl);
        mContactsListView = (ListView) findViewById(R.id.contactsListView);
        mContactsListView.setOnItemClickListener(mContactsListClickListener);
//        mContactsListView.setOnCreateContextMenuListener(mContactsListContextMenuListener);
        mContactsListView.setOnScrollListener(listViewOnScrollListener);
        mContactsListView.setOnFocusChangeListener(new OnFocusChangeListener() {
			
			@Override
			public void onFocusChange(View v, boolean hasFocus) {
				//System.out.println("dddddddddd");
				
			}
		});
        mContactsListView.setAdapter(mContactAdapter);
        mContactsListView.setOnItemSelectedListener(mContactsSelectedListener);
        mQueryHandler = new QueryHandler(this);

        if (!resolveIntent() && icicle != null) {
            super.onRestoreInstanceState(icicle);
        }

        // If the mToneGenerator creation fails, just continue without it.  It is
        // a local audio signal, and is not as important as the dtmf tone itself.
        synchronized (mToneGeneratorLock) {
            if (mToneGenerator == null) {
                try {
                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION,
                            TONE_RELATIVE_VOLUME);
                } catch (RuntimeException e) {
                    Log.w(TAG, "Exception caught while creating local tone generator: " + e);
                    mToneGenerator = null;
                }
            }
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        synchronized(mToneGeneratorLock) {
            if (mToneGenerator != null) {
                mToneStopper.removeMessages(STOP_TONE);
                mToneGenerator.release();
                mToneGenerator = null;
            }
        }
    }

    @Override
    protected void onRestoreInstanceState(Bundle icicle) {
        // Do nothing, state is restored in onCreate() if needed
    }
    
    protected void maybeAddNumberFormatting() {
        mDigits.addTextChangedListener(new PhoneNumberFormattingTextWatcher());
    }
    
    /**
     * Overridden by subclasses to control the resource used by the content view. 
     */
    protected int getContentViewResource() {
    	return R.layout.twelve_key_dialer_dsds;
    }

    private boolean resolveIntent() {
        boolean ignoreState = false;

        // Find the proper intent
//        final Intent intent;
//        if (isChild()) {
//            intent = getParent().getIntent();
//            ignoreState = intent.getBooleanExtra(DialtactsActivity.EXTRA_IGNORE_STATE, false);
//        } else {
//            intent = getIntent();
//        }
//        // Log.i(TAG, "==> resolveIntent(): intent: " + intent);
//
//        // by default we are not adding a call.
//        mIsAddCallMode = false;
//
//        // By default we don't show the "dialpad chooser" UI.
//        boolean needToShowDialpadChooser = false;
//
//        // Resolve the intent
//        final String action = intent.getAction();
//        if (Intent.ACTION_DIAL.equals(action) || Intent.ACTION_VIEW.equals(action)) {
//        	if(Intent.ACTION_DIAL.equals(action)){
//        		isActivityRequestSendCall=true;
//        		mRequestIntent=intent;
//        	}
//            // see if we are "adding a call" from the InCallScreen; false by default.
//            mIsAddCallMode = intent.getBooleanExtra(ADD_CALL_MODE_KEY, false);
//            Uri uri = intent.getData();
//            if (uri != null) {
//                if ("tel".equals(uri.getScheme())) {
//                    // Put the requested number into the input area
//                    String data = uri.getSchemeSpecificPart();
//                    setFormattedDigits(data);
//                } else {
//                    String type = intent.getType();
//                    if (People.CONTENT_ITEM_TYPE.equals(type)
//                            || Phones.CONTENT_ITEM_TYPE.equals(type)) {
//                        // Query the phone number
//                        Cursor c = getContentResolver().query(intent.getData(),
//                                new String[] {PhonesColumns.NUMBER}, null, null, null);
//                        if (c != null) {
//                            if (c.moveToFirst()) {
//                                // Put the number into the input area
//                                setFormattedDigits(c.getString(0));
//                            }
//                            c.close();
//                        }
//                    }
//                }
//            }
//        } else if (Intent.ACTION_MAIN.equals(action)) {
//            // The MAIN action means we're bringing up a blank dialer
//            // (e.g. by selecting the Home shortcut, or tabbing over from
//            // Contacts or Call log.)
//            //
//            // At this point, IF there's already an active call, there's a
//            // good chance that the user got here accidentally (but really
//            // wanted the in-call dialpad instead).  So we bring up an
//            // intermediate UI to make the user confirm what they really
//            // want to do.
//            if (phoneIsInUse()) {
//                // Log.i(TAG, "resolveIntent(): phone is in use; showing dialpad chooser!");
//                needToShowDialpadChooser = true;
//            }
//        }

        // Bring up the "dialpad chooser" IFF we need to make the user
        // confirm which dialpad they really want.
//        showDialpadChooser(needToShowDialpadChooser);

        return ignoreState;
    }

    protected void setFormattedDigits(String data) {
        // strip the non-dialable numbers out of the data string.
        String dialString = PhoneNumberUtils.extractNetworkPortion(data);
        dialString = PhoneNumberUtils.formatNumber(dialString);
        dialString = PhoneNumberUtils.stripSeparators(dialString);
        if (!TextUtils.isEmpty(dialString)) {
            Editable digits = mDigits.getText();
            digits.replace(0, digits.length(), dialString);
            // for some reason this isn't getting called in the digits.replace call above..
            // but in any case, this will make sure the background drawable looks right
            afterTextChanged(digits);
        }
    }

    @Override
    protected void onNewIntent(Intent newIntent) {
        setIntent(newIntent);
        resolveIntent();
    }
    
    @Override
    protected void onPostCreate(Bundle savedInstanceState) {
        super.onPostCreate(savedInstanceState);
        // This can't be done in onCreate(), since the auto-restoring of the digits
        // will play DTMF tones for all the old digits if it is when onRestoreSavedInstanceState()
        // is called. This method will be called every time the activity is created, and
        // will always happen after onRestoreSavedInstanceState().
        mDigits.addTextChangedListener(this);
    }
    
    private void setupKeypad() {
        // Setup the listeners for the buttons
        View view = findViewById(R.id.one);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);

        view = findViewById(R.id.two);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.three);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.four);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.five);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.six);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.seven);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.eight);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.nine);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);
        
        view = findViewById(R.id.star);
        view.setOnClickListener(this);

        view = findViewById(R.id.zero);
        view.setOnClickListener(this);
        view.setOnLongClickListener(this);

        findViewById(R.id.pound).setOnClickListener(this);
//        if (mIsDsds) {
//        	mBtnCall1 = (Button) findViewById(R.id.callmark1);
//        	mBtnCall1.setOnClickListener(this);
//        	
//        	mBtnCall2 = (Button) findViewById(R.id.callmark2);
//        	mBtnCall2.setOnClickListener(this);
//        	setTextOnCallButton();
//        }else {
//        	((Button)findViewById(R.id.callmark)).setOnClickListener(this);
//        }
        
//    	mBtnCall1 = (Button) findViewById(R.id.callmark1);
//    	mBtnCall1.setOnClickListener(this);
//    	
//    	mBtnCall2 = (Button) findViewById(R.id.callmark2);
//    	mBtnCall2.setOnClickListener(this);
//    	
//    	mBtnEmergencyCall=(Button) findViewById(R.id.callmark);
//    	mBtnEmergencyCall.setOnClickListener(this);
//    	
//    	setTextOnCallButton();
//        
////      findViewById(R.id.plus).setOnClickListener(this);
//        mShowHideKeypad = (ImageButton)findViewById(R.id.pop_up_down);
        mShowHideKeypad.setOnClickListener(this);
    }

    private void setTextOnCallButton() {
    	
		TelephonyManager lPhone1 = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
		TelephonyManager lPhone2 = (TelephonyManager) getSystemService(TELEPHONY_SERVICE_TWO);
		//lPhone1=null;
		//lPhone2=null;
		
//		if(lPhone1==null){
//			mBtnCall1.setEnabled(false);
//			//mBtnCall1.setBackgroundColor(Color.GRAY);
//			mBtnCall1.setVisibility(View.GONE);
//		}
//		if(lPhone2==null){
//			mBtnCall2.setEnabled(false);
//			//mBtnCall2.setBackgroundColor(Color.GRAY);
//			mBtnCall2.setVisibility(View.GONE);
//		}
//		if (null == lPhone2 && null == lPhone1) {
//			mBtnCall1.setVisibility(View.GONE);
//			mBtnCall2.setVisibility(View.GONE);
//			mBtnEmergencyCall.setVisibility(View.VISIBLE);
//			 return;
//		}
		

//        if (phone1Type == TelephonyManager.PHONE_TYPE_GSM) {
//        	mCall1.setText(R.string.call_button_gsm);
//        } else if (phone1Type == TelephonyManager.PHONE_TYPE_CDMA) {
//        	mCall1.setText(R.string.call_button_cdma);
//        }
//        
//        if (phone2Type == TelephonyManager.PHONE_TYPE_GSM) {
//        	 if ( phone2Type == phone1Type ) {
//        		 mCall1.setText(R.string.call_button_gsm1);
//        		 mCall2.setText(R.string.call_button_gsm2);
//        	 } else {
//        		 mCall2.setText(R.string.call_button_gsm);
//        	 }
//        	
//         } else if (phone2Type == TelephonyManager.PHONE_TYPE_CDMA) {
//        	 
//        	 if ( phone2Type == phone1Type ) {
//        		 mCall1.setText(R.string.call_button_cdma1);
//        		 mCall2.setText(R.string.call_button_cdma2);
//        	 } else {
//        		 mCall2.setText(R.string.call_button_cdma);
//        	 }
//        }
        
//        if (Settings.System.getInt(getContentResolver(),Settings.System.USE_NICKNAME, 0) == 1) {
//        	String slot1NickName = Settings.System.getString(getContentResolver(),Settings.System.SLOT1_NICKNAME);
//        	String slot2NickName = Settings.System.getString(getContentResolver(),Settings.System.SLOT2_NICKNAME);
//        	
//        	if (!TextUtils.isEmpty(slot1NickName)) mBtnCall1.setText(slot1NickName);
//        	if (!TextUtils.isEmpty(slot2NickName)) mBtnCall2.setText(slot2NickName);
//        }
		
	}

	@Override
    protected void onResume() {
        super.onResume();
        
        // retrieve the DTMF tone play back setting.
        mDTMFToneEnabled = Settings.System.getInt(getContentResolver(),
                Settings.System.DTMF_TONE_WHEN_DIALING, 1) == 1;

        // if the mToneGenerator creation fails, just continue without it.  It is 
        // a local audio signal, and is not as important as the dtmf tone itself.
        synchronized(mToneGeneratorLock) {
            if (mToneGenerator == null) {
                try {
                    mToneGenerator = new ToneGenerator(AudioManager.STREAM_NOTIFICATION,
                            TONE_RELATIVE_VOLUME);
                } catch (RuntimeException e) {
                    Log.w(TAG, "Exception caught while creating local tone generator: " + e);
                    mToneGenerator = null;
                }
            }
        }
        
        Activity parent = getParent();
        // See if we were invoked with a DIAL intent. If we were, fill in the appropriate
        // digits in the dialer field.
//        if (parent != null && parent instanceof DialtactsActivity) {
//            Uri dialUri = ((DialtactsActivity) parent).getAndClearDialUri();
//            if (dialUri != null) {
//                resolveIntent();
//            }
//        }

        // While we're in the foreground, listen for phone state changes,
        // purely so that we can take down the "dialpad chooser" if the
        // phone becomes idle while the chooser UI is visible.
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);

        // Potentially show hint text in the mDigits field when the user
        // hasn't typed any digits yet.  (If there's already an active call,
        // this hint text will remind the user that he's about to add a new
        // call.)
        //
        // TODO: consider adding better UI for the case where *both* lines
        // are currently in use.  (Right now we let the user try to add
        // another call, but that call is guaranteed to fail.  Perhaps the
        // entire dialer UI should be disabled instead.)
        if (phoneIsInUse()) {
            mDigitsShow.setHint(R.string.dialerDialpadHintText);
        } else {
            // Common case; no hint necessary.
            mDigitsShow.setHint(null);

            // Also, a sanity-check: the "dialpad chooser" UI should NEVER
            // be visible if the phone is idle!
//            showDialpadChooser(false);
        }
        
        if(!mDialerDrawer.isOpened()){
            //mDialerDrawer.animateToggle();
        	mDialerDrawer.open();
        }
        setDigitsShowOrHideWithAnima();
        //startQuery();
        mContactList=ContactsCalllogDBUtils.getContactList(getApplicationContext(), null);
		mCallLogList=ContactsCalllogDBUtils.getCallLogs(getApplicationContext(),null);
		afterQuery();
		
    }

    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
        if (hasFocus) {
            // Hide soft keyboard, if visible (it's fugly over button dialer).
            // The only known case where this will be true is when launching the dialer with
            // ACTION_DIAL via a soft keyboard.  we dismiss it here because we don't
            // have a window token yet in onCreate / onNewIntent
            InputMethodManager inputMethodManager = (InputMethodManager)
                    getSystemService(Context.INPUT_METHOD_SERVICE);
            inputMethodManager.hideSoftInputFromWindow(mDigitsShow.getWindowToken(), 0);            
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Stop listening for phone state changes.
        TelephonyManager telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
        telephonyManager.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);

        synchronized(mToneGeneratorLock) {
            if (mToneGenerator != null) {
                mToneStopper.removeMessages(STOP_TONE);
                mToneGenerator.release();
                mToneGenerator = null;
            }
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
//        mAddToContactMenuItem = menu.add(0, 0, 0, R.string.recentCalls_addToContact)
//                .setIcon(android.R.drawable.ic_menu_add);
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        // We never show a menu if the "choose dialpad" UI is up.
//        if (dialpadChooserVisible()) {
//            return false;
//        }

//        CharSequence digits = mDigits.getText();
//        if (digits == null || !TextUtils.isGraphic(digits)) {
//            mAddToContactMenuItem.setVisible(false);
//        } else {
//            // Put the current digits string into an intent
//            Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
//            intent.putExtra(Insert.PHONE, mDigits.getText());
//            intent.setType(People.CONTENT_ITEM_TYPE);
//            mAddToContactMenuItem.setIntent(intent);
//            mAddToContactMenuItem.setVisible(true);
//        }
        return true;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        switch (keyCode) {
//		    case KeyEvent.KEYCODE_BACK:
//		    	//System.out.println(TAG + "onKeyDown keyCode is KEYCODE_BACK");
//		    	//System.out.println(TAG + "isActivityRequestSendCall:"+isActivityRequestSendCall);
//		    	if(isActivityRequestSendCall){
//		    		setResult(Activity.RESULT_OK,mRequestIntent);
//		    		finish();
//		    	}
//			   break;
            case KeyEvent.KEYCODE_CALL: {
                long callPressDiff = SystemClock.uptimeMillis() - event.getDownTime();
                if (callPressDiff >= ViewConfiguration.getLongPressTimeout()) {
                    // Launch voice dialer
                    Intent intent = new Intent(Intent.ACTION_VOICE_COMMAND);
                    intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    try {
                        startActivity(intent);
                    } catch (ActivityNotFoundException e) {
                    }
                }
                return true;
            }
            case KeyEvent.KEYCODE_1: {
                long timeDiff = SystemClock.uptimeMillis() - event.getDownTime(); 
                if (timeDiff >= ViewConfiguration.getLongPressTimeout()) {
                    // Long press detected, call voice mail
                    callVoicemail();
                    return true;
                }
            }
        }
        if(mDialerDrawer.isOpened()){
            switch(keyCode){
                case KeyEvent.KEYCODE_STAR:
                    String numberNow = mDigits.getText().toString();
                    long currentTime = SystemClock.elapsedRealtime();
                    if(numberNow.endsWith("*") 
                        && currentTime - mStarKeyPressedTime < DOUBLE_CLICK_TAP){
                        mDigits.getText().delete(mDigits.length()-1, mDigits.length());
                        mDigits.append(",");
                    }else if(numberNow.endsWith(",") 
                        && currentTime - mStarKeyPressedTime < DOUBLE_CLICK_TAP){
                        mDigits.getText().delete(mDigits.length()-1, mDigits.length());
                        mDigits.append(";");
                    }else if(numberNow.endsWith(";") 
                        && currentTime - mStarKeyPressedTime < DOUBLE_CLICK_TAP){
                        mDigits.getText().delete(mDigits.length()-1, mDigits.length());
                        mDigits.append("*");
                    }else{
                         mDigits.onKeyDown(keyCode, event);
                    }
                    mStarKeyPressedTime = currentTime;
                    return true;
                case KeyEvent.KEYCODE_0:
                case KeyEvent.KEYCODE_1:
                case KeyEvent.KEYCODE_2:
                case KeyEvent.KEYCODE_3:
                case KeyEvent.KEYCODE_4:
                case KeyEvent.KEYCODE_5:
                case KeyEvent.KEYCODE_6:
                case KeyEvent.KEYCODE_7:
                case KeyEvent.KEYCODE_8:
                case KeyEvent.KEYCODE_9:
                case KeyEvent.KEYCODE_POUND:
                    mDigits.onKeyDown(keyCode, event);
                    return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    
    private void analogKeyPressed(String number){
    	char key;
    	for(int i=0;i<number.length();i++){
    		//key=Integer.parseInt(number.substring(i,i+1));
    		key=number.charAt(i);
    		switch (key) {
			case '0':
				 keyPressed(KeyEvent.KEYCODE_0);
				break;
			case '1':
				 keyPressed(KeyEvent.KEYCODE_1);
				break;
			case '2':
				 keyPressed(KeyEvent.KEYCODE_2);
				break;
			case '3':
				 keyPressed(KeyEvent.KEYCODE_3);
				break;
			case '4':
				 keyPressed(KeyEvent.KEYCODE_4);
				break;
			case '5':
				 keyPressed(KeyEvent.KEYCODE_5);
				break;
			case '6':
				 keyPressed(KeyEvent.KEYCODE_6);
				break;
			case '7':
				 keyPressed(KeyEvent.KEYCODE_7);
				break;
			case '8':
				 keyPressed(KeyEvent.KEYCODE_8);
				break;
			case '9':
				 keyPressed(KeyEvent.KEYCODE_9);
				break;
			case '#':
				 keyPressed(KeyEvent.KEYCODE_POUND);
				break;
			case '*':
				 keyPressed(KeyEvent.KEYCODE_STAR);
				break;

			default:
				break;
			}
    	}
    }
    
    private void keyPressed(int keyCode) {
//        vibrate();
        KeyEvent event = new KeyEvent(KeyEvent.ACTION_DOWN, keyCode);
        mDigits.onKeyDown(keyCode, event);
    }

    public boolean onKey(View view, int keyCode, KeyEvent event) {
        switch (view.getId()) {
            case R.id.digitsShow:
                if (keyCode == KeyEvent.KEYCODE_ENTER) {
                    placeCall();
                    return true;
                }
                break;
        }
        return false;
    }

    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.one: {
                playTone(ToneGenerator.TONE_DTMF_1);
                keyPressed(KeyEvent.KEYCODE_1);
                return;
            }
            case R.id.two: {
                playTone(ToneGenerator.TONE_DTMF_2);
                keyPressed(KeyEvent.KEYCODE_2);
                return;
            }
            case R.id.three: {
                playTone(ToneGenerator.TONE_DTMF_3);
                keyPressed(KeyEvent.KEYCODE_3);
                return;
            }
            case R.id.four: {
                playTone(ToneGenerator.TONE_DTMF_4);
                keyPressed(KeyEvent.KEYCODE_4);
                return;
            }
            case R.id.five: {
                playTone(ToneGenerator.TONE_DTMF_5);
                keyPressed(KeyEvent.KEYCODE_5);
                return;
            }
            case R.id.six: {
                playTone(ToneGenerator.TONE_DTMF_6);
                keyPressed(KeyEvent.KEYCODE_6);
                return;
            }
            case R.id.seven: {
                playTone(ToneGenerator.TONE_DTMF_7);
                keyPressed(KeyEvent.KEYCODE_7);
                return;
            }
            case R.id.eight: {
                playTone(ToneGenerator.TONE_DTMF_8);
                keyPressed(KeyEvent.KEYCODE_8);
                return;
            }
            case R.id.nine: {
                playTone(ToneGenerator.TONE_DTMF_9);
                keyPressed(KeyEvent.KEYCODE_9);
                return;
            }
            case R.id.zero: {
                playTone(ToneGenerator.TONE_DTMF_0);
                keyPressed(KeyEvent.KEYCODE_0);
                return;
            }
            case R.id.pound: {
                playTone(ToneGenerator.TONE_DTMF_P);
                keyPressed(KeyEvent.KEYCODE_POUND);
                return;
            }
            case R.id.star: {
                playTone(ToneGenerator.TONE_DTMF_S);
                String numberNow = mDigits.getText().toString();
                long currentTime = SystemClock.elapsedRealtime();
                if(numberNow.endsWith("*") 
                    && currentTime - mStarKeyPressedTime < DOUBLE_CLICK_TAP){
                    mDigits.getText().delete(mDigits.length()-1, mDigits.length());
                    mDigits.append(",");
                }else if(numberNow.endsWith(",") 
                    && currentTime - mStarKeyPressedTime < DOUBLE_CLICK_TAP){
                    mDigits.getText().delete(mDigits.length()-1, mDigits.length());
                    mDigits.append(";");
                }else if(numberNow.endsWith(";") 
                    && currentTime - mStarKeyPressedTime < DOUBLE_CLICK_TAP){
                    mDigits.getText().delete(mDigits.length()-1, mDigits.length());
                    mDigits.append("*");
                }else{
                    keyPressed(KeyEvent.KEYCODE_STAR);
                }
                mStarKeyPressedTime = currentTime;
                return;
            }
            case R.id.backspace: {
            	isDelNumber = true;
                playTone(ToneGenerator.TONE_DTMF_B);
                keyPressed(KeyEvent.KEYCODE_DEL);
                return;
            }
            case R.id.digitsShow:
            	break;

//            case R.id.callmark1: {
//                placeCall(1);
//                return;
//            }
//            case R.id.callmark2: {
//                placeCall(2);
//                return;
//            }
//            case R.id.callmark: {
//                //placeCall();
//            	Intent intent = new Intent();
//            	intent.setAction("com.android.phone.EmergencyDialer.DIAL");
//            	startActivity(intent);
//                return;
//            }

//            case R.id.pop_up_down: {
//                mLlShowDailpad.setVisibility(View.VISIBLE);
//                //mDialerDrawer.animateToggle();
//                mDialerDrawer.close();
//                return;
//            }
            case R.id.showDialPadBtn:
             	 mDialerDrawer.open();
          	     System.out.println("show DialPadBtn ");
            	 mLlShowDailpad.setVisibility(View.GONE);

//            	 mDialerDrawer.animateToggle();
            	return;
            	
            case R.id.createContactsItemRl: {
//              playTone(ToneGenerator.TONE_DTMF_A);
              if(mDigits.getText() != null && mDigits.getText().length() != 0 && mDialerDrawer.isOpened()){
//                  Intent intent = new Intent("com.android.contacts.action.SHOW_OR_CREATE_CONTACT");
//                  intent.setData(Uri.fromParts("tel", mDigits.getText().toString(), null));
//                  intent.putExtra(Insert.PHONE, mDigits.getText());
//                  intent.setType(People.CONTENT_ITEM_TYPE);
//                  startActivity(intent);
              	
//              	if(mCreateContactMenuWindow==null){
//              		initCreateContactMenuWindow();
//              	}
//              	mCreateContactMenuWindow.show();
              }
              return;
          }
          case R.id.addToExistingContactItemRl:{
          	if(mDigits.getText() != null && mDigits.getText().length() != 0 && mDialerDrawer.isOpened()){
          		Toast.makeText(this, "go to add to existing contact", 0).show();
          	}
          }
          	return;
//          case R.id.createContactBtn:{
//        	  Toast.makeText(this, "go to create contact", 0).show();
//          }
//        	return;  
//          case R.id.addToExsitingContactBtn:{
//        	  Toast.makeText(this, "go to add to existing contact", 0).show();
//          }
//        	return; 
//          case R.id.cancelBtn:{
////        	  mCreateContactMenuWindow.close();
//          }
//        	return; 
        }
    }
    
//    private void initCreateContactMenuWindow(){
//    	mCreateContactMenuWindow=new MenuWindow(this, R.layout.twelve_key_dialer_dsds);
//    	View view=LayoutInflater.from(this).inflate(R.layout.create_contact_menuwindow_content, null);
//    	view.findViewById(R.id.createContactBtn).setOnClickListener(this);
//    	view.findViewById(R.id.addToExsitingContactBtn).setOnClickListener(this);
//    	view.findViewById(R.id.cancelBtn).setOnClickListener(this);
//    	mCreateContactMenuWindow.setContentView(view);
//    	mCreateContactMenuWindow.setMargins(10, 30, 10, 20);
//    }

    public boolean onLongClick(View view) {
        final Editable digits = mDigits.getText();
        int id = view.getId();
        switch (id) {
            case R.id.backspace: {
                digits.clear();
                mDigitsShow.setTextSize(25);
                return true;
            }
            case R.id.one: {
                if (digits.length() == 0) {
                    callVoicemail();
                    return true;
                }
                return false;
            }
            case R.id.two:
                return rapidCall(2);
            case R.id.three:
                return rapidCall(3);
            case R.id.four:
                return rapidCall(4);
            case R.id.five:
                return rapidCall(5);
            case R.id.six:
                return rapidCall(6);
            case R.id.seven:
                return rapidCall(7);
            case R.id.eight:
                return rapidCall(8);
            case R.id.nine:
                return rapidCall(9);
            case R.id.zero: {
                keyPressed(KeyEvent.KEYCODE_PLUS);
                return true;
            }
            case R.id.digitsShow:
            	return true;
        }
        return false;
    }

    private boolean rapidCall(int key){
        Uri rapidUri = ContentUris.withAppendedId(Uri.parse("content://com.android.contacts/speed_dial"), key);
        Cursor c = getContentResolver().query(rapidUri,
                new String[] {Data.DATA1}, null, null, null);
        if (c != null) {
            if (c.moveToFirst()) {
                Intent intent = new Intent(Intent.ACTION_DIAL,
                        Uri.fromParts("tel", c.getString(0), null));
                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);
                mDigits.getText().clear();
                finish();
                c.close();
                return true;
            }else{
                c.close();
                Log.d(TAG, "in rapid dial cursor.moveToFirst is null!");
                return false;
            }
        }else{
        	Log.d(TAG, "rapid dial cursor is null!");
            return false;
        }
    }
    
    void callVoicemail() {
        Intent intent = new Intent(Intent.ACTION_DIAL,
                Uri.fromParts("voicemail", "", null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        mDigits.getText().clear();
        finish();
    }

    void placeCall(int phoneid) {
        String number = null;
        if(mDialerDrawer.isOpened()) {
            number = mDigits.getText().toString();
        }else{
            if(mSelectedNumber != null){
                number = mSelectedNumber;
            }
        }
        if (number == null || !TextUtils.isGraphic(number)) {
            // There is no number entered.
            playTone(ToneGenerator.TONE_PROP_NACK);
            return;
        }
        Intent testintent = new Intent(Intent.ACTION_CALL,
                Uri.fromParts("tel", number, null));
        startActivity(testintent);
        mDigits.getText().clear();
//        finish();
        
        
//        Intent intent = new Intent(Intent.ACTION_CALL_PRIVILEGED,
//                Uri.fromParts("tel", number, null));
//        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//        intent.putExtra(EXTRA_PHONE_ID, phoneid-1);
//        startActivity(intent);
//        mDigits.getText().clear();
//        finish();
    }
    
    void placeCall() {
        String number = null;
        if(mDialerDrawer.isOpened()) {
            number = mDigits.getText().toString();
        }else{
            if(mSelectedNumber != null){
                number = mSelectedNumber;
            }
        }
        if (number == null || !TextUtils.isGraphic(number)) {
            // There is no number entered.
            playTone(ToneGenerator.TONE_PROP_NACK);
            return;
        }
        Intent intent = new Intent(Intent.ACTION_DIAL,
                Uri.fromParts("tel", number, null));
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(intent);
        mDigits.getText().clear();
//        finish();
    }

    Handler mToneStopper = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case STOP_TONE:
                    synchronized(mToneGeneratorLock) {
                        if (mToneGenerator == null) {
                            Log.w(TAG, "mToneStopper: mToneGenerator == null");
                        } else {
                            mToneGenerator.stopTone();
                        }
                    }
                    break;
            }
        }
    };

    /**
     * Plays the specified tone for TONE_LENGTH_MS milliseconds.
     *
     * The tone is played locally, using the audio stream for phone calls.
     * Tones are played only if the "Audible touch tones" user preference
     * is checked, and are NOT played if the device is in silent mode.
     *
     * @param tone a tone code from {@link ToneGenerator}
     */
    void playTone(int tone) {
        // if local tone playback is disabled, just return.
        if (!mDTMFToneEnabled) {
            return;
        }

        // Also do nothing if the phone is in silent mode.
        // We need to re-check the ringer mode for *every* playTone()
        // call, rather than keeping a local flag that's updated in
        // onResume(), since it's possible to toggle silent mode without
        // leaving the current activity (via the ENDCALL-longpress menu.)
        AudioManager audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
        int ringerMode = audioManager.getRingerMode();
        if ((ringerMode == AudioManager.RINGER_MODE_SILENT)
            || (ringerMode == AudioManager.RINGER_MODE_VIBRATE)) {
            return;
        }

        synchronized(mToneGeneratorLock) {
            if (mToneGenerator == null) {
                Log.w(TAG, "playTone: mToneGenerator == null, tone: "+tone);
                return;
            }
            
            // Remove pending STOP_TONE messages
            mToneStopper.removeMessages(STOP_TONE);
    
            // Start the new tone (will stop any playing tone)
            mToneGenerator.startTone(tone);
            mToneStopper.sendEmptyMessageDelayed(STOP_TONE, TONE_LENGTH_MS);
        }
    }

    /**
     * Brings up the "dialpad chooser" UI in place of the usual Dialer
     * elements (the textfield/button and the dialpad underneath).
     *
     * We show this UI if the user brings up the Dialer while a call is
     * already in progress, since there's a good chance we got here
     * accidentally (and the user really wanted the in-call dialpad instead).
     * So in this situation we display an intermediate UI that lets the user
     * explicitly choose between the in-call dialpad ("Use touch tone
     * keypad") and the regular Dialer ("Add call").  (Or, the option "Return
     * to call in progress" just goes back to the in-call UI with no dialpad
     * at all.)
     *
     * @param enabled If true, show the "dialpad chooser" instead
     *                of the regular Dialer UI
     */
//    private void showDialpadChooser(boolean enabled) {
//        if (enabled) {
//            // Log.i(TAG, "Showing dialpad chooser!");
//            mContactsList.setVisibility(View.GONE);
//            if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.GONE);
//            mDialpadChooser.setVisibility(View.VISIBLE);
//
//            // Instantiate the DialpadChooserAdapter and hook it up to the
//            // ListView.  We do this only once.
//            if (mDialpadChooserAdapter == null) {
//                mDialpadChooserAdapter = new DialpadChooserAdapter(this);
//                mDialpadChooser.setAdapter(mDialpadChooserAdapter);
//            }
//        } else {
//            // Log.i(TAG, "Displaying normal Dialer UI.");
//            mContactsList.setVisibility(View.VISIBLE);
//            if (mDialerDrawer != null) mDialerDrawer.setVisibility(View.VISIBLE);
//            mDialpadChooser.setVisibility(View.GONE);
//        }
//    }

    /**
     * @return true if we're currently showing the "dialpad chooser" UI.
     */
//    private boolean dialpadChooserVisible() {
//        return mDialpadChooser.getVisibility() == View.VISIBLE;
//    }

    /**
     * Simple list adapter, binding to an icon + text label
     * for each item in the "dialpad chooser" list.
     */
    private static class DialpadChooserAdapter extends BaseAdapter {
        private LayoutInflater mInflater;

        // Simple struct for a single "choice" item.
        static class ChoiceItem {
            String text;
            Bitmap icon;
            int id;

            public ChoiceItem(String s, Bitmap b, int i) {
                text = s;
                icon = b;
                id = i;
            }
        }

        // IDs for the possible "choices":
        static final int DIALPAD_CHOICE_USE_DTMF_DIALPAD = 101;
        static final int DIALPAD_CHOICE_RETURN_TO_CALL = 102;
        static final int DIALPAD_CHOICE_ADD_NEW_CALL = 103;

        private static final int NUM_ITEMS = 3;
        private ChoiceItem mChoiceItems[] = new ChoiceItem[NUM_ITEMS];

        public DialpadChooserAdapter(Context context) {
            // Cache the LayoutInflate to avoid asking for a new one each time.
            mInflater = LayoutInflater.from(context);

            // Initialize the possible choices.
            // TODO: could this be specified entirely in XML?

            // - "Use touch tone keypad"
            mChoiceItems[0] = new ChoiceItem(
                    context.getString(R.string.dialer_useDtmfDialpad),
                    BitmapFactory.decodeResource(context.getResources(),
                                                 R.drawable.ic_dialer_fork_tt_keypad),
                    DIALPAD_CHOICE_USE_DTMF_DIALPAD);

            // - "Return to call in progress"
            mChoiceItems[1] = new ChoiceItem(
                    context.getString(R.string.dialer_returnToInCallScreen),
                    BitmapFactory.decodeResource(context.getResources(),
                                                 R.drawable.ic_dialer_fork_current_call),
                    DIALPAD_CHOICE_RETURN_TO_CALL);

            // - "Add call"
            mChoiceItems[2] = new ChoiceItem(
                    context.getString(R.string.dialer_addAnotherCall),
                    BitmapFactory.decodeResource(context.getResources(),
                                                 R.drawable.ic_dialer_fork_add_call),
                    DIALPAD_CHOICE_ADD_NEW_CALL);
        }

        public int getCount() {
            return NUM_ITEMS;
        }

        /**
         * Return the ChoiceItem for a given position.
         */
        public Object getItem(int position) {
            return mChoiceItems[position];
        }

        /**
         * Return a unique ID for each possible choice.
         */
        public long getItemId(int position) {
            return position;
        }

        /**
         * Make a view for each row.
         */
        public View getView(int position, View convertView, ViewGroup parent) {
            // When convertView is non-null, we can reuse it (there's no need
            // to reinflate it.)
//            if (convertView == null) {
//                convertView = mInflater.inflate(R.layout.dialpad_chooser_list_item, null);
//            }
//
//            TextView text = (TextView) convertView.findViewById(R.id.text);
//            text.setText(mChoiceItems[position].text);
//
//            ImageView icon = (ImageView) convertView.findViewById(R.id.icon);
//            icon.setImageBitmap(mChoiceItems[position].icon);

            return convertView;
        }
    }

    /**
     * Handle clicks from the dialpad chooser.
     */
//    public void onItemClick(AdapterView parent, View v, int position, long id) {
//        DialpadChooserAdapter.ChoiceItem item =
//                (DialpadChooserAdapter.ChoiceItem) parent.getItemAtPosition(position);
//        int itemId = item.id;
//        switch (itemId) {
//            case DialpadChooserAdapter.DIALPAD_CHOICE_USE_DTMF_DIALPAD:
//                // Log.i(TAG, "DIALPAD_CHOICE_USE_DTMF_DIALPAD");
//                // Fire off an intent to go back to the in-call UI
//                // with the dialpad visible.
//                returnToInCallScreen(true);
//                break;
//
//            case DialpadChooserAdapter.DIALPAD_CHOICE_RETURN_TO_CALL:
//                // Log.i(TAG, "DIALPAD_CHOICE_RETURN_TO_CALL");
//                // Fire off an intent to go back to the in-call UI
//                // (with the dialpad hidden).
//                returnToInCallScreen(false);
//                break;
//
//            case DialpadChooserAdapter.DIALPAD_CHOICE_ADD_NEW_CALL:
//                // Log.i(TAG, "DIALPAD_CHOICE_ADD_NEW_CALL");
//                // Ok, guess the user really did want to be here (in the
//                // regular Dialer) after all.  Bring back the normal Dialer UI.
//                showDialpadChooser(false);
//                break;
//
//            default:
//                Log.w(TAG, "onItemClick: unexpected itemId: " + itemId);
//                break;
//        }
//    }

    /**
     * Returns to the in-call UI (where there's presumably a call in
     * progress) in response to the user selecting "use touch tone keypad"
     * or "return to call" from the dialpad chooser.
     */
    private void returnToInCallScreen(boolean showDialpad) {
//        try {
//            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
//            if (phone != null) phone.showCallScreenWithDialpad(showDialpad);
//        } catch (RemoteException e) {
//            Log.w(TAG, "phone.showCallScreenWithDialpad() failed", e);
//        }

        // Finally, finish() ourselves so that we don't stay on the
        // activity stack.
        // Note that we do this whether or not the showCallScreenWithDialpad()
        // call above had any effect or not!  (That call is a no-op if the
        // phone is idle, which can happen if the current call ends while
        // the dialpad chooser is up.  In this case we can't show the
        // InCallScreen, and there's no point staying here in the Dialer,
        // so we just take the user back where he came from...)
        finish();
    }

    /**
     * @return true if the phone is "in use", meaning that at least one line
     *              is active (ie. off hook or ringing or dialing).
     */
    private boolean phoneIsInUse() {
        boolean phoneInUse = false;
//        try {
//            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
//            if (phone != null) phoneInUse = !phone.isIdle();
//        } catch (RemoteException e) {
//            Log.w(TAG, "phone.isIdle() failed", e);
//        }
        return phoneInUse;
    }
    
    private void measureView(View view){
		int w = View.MeasureSpec.makeMeasureSpec(0,
				View.MeasureSpec.UNSPECIFIED);
		int h = View.MeasureSpec.makeMeasureSpec(0,
				View.MeasureSpec.UNSPECIFIED);
		view.measure(w, h);
    }
    private void setDigitsShowOrHideWithAnima(){
    	if(notShowOrHideDigitsView){
    		notShowOrHideDigitsView=false;
    		return;
    	}
    	 if(mDigits.getText().toString().length()>0){
    		 if(mShowDigitsLl.getVisibility()==View.GONE){
    			 mShowDigitsLl.setVisibility(View.VISIBLE);
    			 measureView(mShowDigitsLl);
   	             TranslateAnimation rAnimation = new TranslateAnimation(0, 0,
	                    -mShowDigitsLl.getMeasuredHeight(), 0);
    	          rAnimation.setDuration(300);
    	          mContactsListViewLl.startAnimation(rAnimation);
    		 }
    		 mShowDigitsLl.setVisibility(View.VISIBLE);
         }else{
        	 if(mShowDigitsLl.getVisibility()==View.VISIBLE){
    			 //measureView(mShowDigitsLl);
   	             TranslateAnimation rAnimation = new TranslateAnimation(0, 0,
   	            		mShowDigitsLl.getMeasuredHeight(), 0);
   	             //Log.d(TAG, "mShowDigitsLl.getMeasuredHeight():"+mShowDigitsLl.getMeasuredHeight());
    	          rAnimation.setDuration(300);
    	          mContactsListViewLl.startAnimation(rAnimation);
    	          
    	          TranslateAnimation rAnimation2 = new TranslateAnimation(0, 0,
    	   	            		0, -mShowDigitsLl.getMeasuredHeight());
    	          rAnimation2.setDuration(300);
    	          mShowDigitsLl.startAnimation(rAnimation2);
        	 }
        	 mShowDigitsLl.setVisibility(View.GONE);
         }
    }
    
    private void startQuery() {

        final String cond = mDigits.getText().toString();
       
        // Cancel any pending queries
//        Log.d(TAG, "querey number is >>>> " + cond);
//          mQueryHandler.cancelOperation(QUERY_TOKEN);
          
//        mQueryHandler.startQuery(QUERY_TOKEN, null, PHONES_AND_CALLLOG_CONTENT_URI,
//                PHONES_AND_CALLLOG_PROJECTION, "number LIKE \'%" + cond + "%\'" +
//                " OR dialpad_number_short LIKE \'%" + cond + "%\'" +
//              	 " OR dialpad_number_full LIKE \'%" + cond + "%\'", null, Contacts.DISPLAY_NAME);
        
        //mQueryHandler.startQuery(QUERY_TOKEN, null, CONTACTS_CONTENT_URI, null, null, null, null);
        
        //mContactList=ContactsCalllogDBUtils.getContacts(this);
        //mCallLogList=ContactsCalllogDBUtils.getCallLogs(this);
        mAsyncTaskNumber++;
        new AsyncTask<CopyOfTwelveKeyDialer1, Void, CopyOfTwelveKeyDialer1>() {

			@Override
			protected CopyOfTwelveKeyDialer1 doInBackground(CopyOfTwelveKeyDialer1... params) {
				if(mAsyncTaskNumber==1){
					//mContactList=ContactsCalllogDBUtils.getContacts(getApplicationContext(),cond);	
					mContactList=ContactsCalllogDBUtils.getContactList(getApplicationContext(), cond);
				}
				if(mAsyncTaskNumber==1){
					mCallLogList=ContactsCalllogDBUtils.getCallLogs(getApplicationContext(),cond);
				}
				mAsyncTaskNumber--;
				return params[0];
			}
			
			@Override
			protected void onPostExecute(CopyOfTwelveKeyDialer1 activity) {
				if(mAsyncTaskNumber>1){
					return;
				}
				afterQuery();
			};
        	
		}.execute(this);
       
    }
    
    private void afterQuery(){
    	if(mCallLogList!=null&&mContactList!=null&&mCallLogList.size()>0&&mContactList.size()>0){
			ArrayList<String> nameList=new ArrayList<String>();
			for(int i=0;i<mCallLogList.size();i++){
				nameList.add(mCallLogList.get(i).getName());
			}
			int size=mContactList.size();
			for(int i=size-1;i>=0;i--){
				if(nameList.contains(mContactList.get(i).getName())){
					mContactList.remove(i);
				}
			}
		}
		mContactAdapter.notifyDataSetChanged();
		if(mCallLogList==null&&mContactList==null){
            Message message = this.mHandler.obtainMessage(this.NO_CALLLOG_AND_CONTACTS);
            message.sendToTarget();
		}else if(mCallLogList.size()+mContactList.size()<1){
            Message message = this.mHandler.obtainMessage(this.NO_CALLLOG_AND_CONTACTS);
            message.sendToTarget();
		}else{
            Message message = this.mHandler.obtainMessage(this.HAVE_CALLLOG_AND_CONTACTS);
            message.sendToTarget(); 
		}
    }
    
    
    /**
     * Shared builder used by {@link #formatPhoneNumber(String)} to minimize
     * allocations when formatting phone numbers.
     */
    private static final SpannableStringBuilder sEditable = new SpannableStringBuilder();

    /**
     * Invalid formatting type constant for {@link #sFormattingType}.
     */
    private static final int FORMATTING_TYPE_INVALID = -1;

    /**
     * Cached formatting type for current {@link Locale}, as provided by
     * {@link PhoneNumberUtils#getFormatTypeForLocale(Locale)}.
     */
    private static int sFormattingType = FORMATTING_TYPE_INVALID;
    
    /**
     * Format the given phone number using
     * {@link PhoneNumberUtils#formatNumber(android.text.Editable, int)}. This
     * helper method uses {@link #sEditable} and {@link #sFormattingType} to
     * prevent allocations between multiple calls.
     * <p>
     * Because of the shared {@link #sEditable} builder, <b>this method is not
     * thread safe</b>, and should only be called from the GUI thread.
     */
    private String formatPhoneNumber(String number) {
        // Cache formatting type if not already present
        if (sFormattingType == FORMATTING_TYPE_INVALID) {
            sFormattingType = PhoneNumberUtils.getFormatTypeForLocale(Locale.getDefault());
        }

        sEditable.clear();
        sEditable.append(number);

        PhoneNumberUtils.formatNumber(sEditable, sFormattingType);
        return PhoneNumberUtils.stripSeparators(sEditable.toString());
    }
    
    
    final class MyContactAdapter extends BaseAdapter{
    	LayoutInflater mLayoutInflater=LayoutInflater.from(getApplicationContext());
    	
		@Override
		public int getCount() {
			if((mContactList==null&&mCallLogList==null)||mCallLogList.size()+mContactList.size()==0){
				return 0;
			}
			if(mCallLogList==null||mCallLogList.size()==0){
				return mContactList.size()+1;
			}
			if(mContactList==null||mContactList.size()==0){
				return mCallLogList.size()+1;
			}
			return mCallLogList.size()+mContactList.size()+2; //mContactList.size()
		}

		@Override
		public Object getItem(int position) {
			if(mCallLogList==null||mCallLogList.size()==0){
				if(position==0){
					return null;
				}else{
					return mContactList.get(position-1);
				}
			}
			if(mContactList==null||mContactList.size()==0){
				if(position==0){
					return null;
				}else{
					return mCallLogList.get(position-1);
				}
			}
			if(position==0||position==mCallLogList.size()+1){
				return null;
			}else if(position<mCallLogList.size()+1){
				return mCallLogList.get(position-1);
			}else{
				return mContactList.get(position-mCallLogList.size()-2);
			}
		}

		@Override
		public long getItemId(int position) {
			return position;
		}

		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View view=null;
			
			if(mCallLogList==null||mCallLogList.size()==0){
				if(position==0){
					return getDivideView(R.string.calllog_contacts);
				}else{
					view=getContactsItemContentView(mContactList.get(position-1), convertView);
				}
			}else if(mContactList==null||mContactList.size()==0){
				if(position==0){
					return getDivideView(R.string.calllog_recents);
				}else{
					view = getCallLogItemContentView(mCallLogList.get(position-1), convertView);
				}
			}else{
				if(position==0||position==mCallLogList.size()+1){
					if(position==0){
						return getDivideView(R.string.calllog_recents);
					}else{
						return getDivideView(R.string.calllog_contacts);
					}
				}else if(position<mCallLogList.size()+1){
					view = getCallLogItemContentView(mCallLogList.get(position-1), convertView);
				}else{
					view=getContactsItemContentView(mContactList.get(position-mCallLogList.size()-2), convertView);
				}
			}
			return view;
		}

		private View getCallLogItemContentView(MyCallLog callLog, View convertView) {
			View view;
			ContactsListViewItemViews tempView;
			if(convertView==null||!(convertView.getTag() instanceof ContactsListViewItemViews)){
				view=getContentView();
			}else{
				view=convertView;
			}
			tempView=(ContactsListViewItemViews) view.getTag();
			
			tempView.nameView.setText(callLog.getName());
			String logMsg=CallLogDateUtils.getDateString(getApplicationContext(), callLog.getCallDate())+"  "+getResources().getString(callLog.getCallTypeResId())+"   "
			     +CallLogDateUtils.getDurationTimeString(getApplicationContext(), callLog.getDuration());
			tempView.numberView.setText(logMsg);
			tempView.addressView.setText(callLog.getNumber());
			return view;
		}
		private View getContactsItemContentView(ContactPerson contact, View convertView) {
			View view;
			ContactsListViewItemViews tempView;
			if(convertView==null||!(convertView.getTag() instanceof ContactsListViewItemViews)){
				view=getContentView();
			}else{
				view=convertView;
			}
			tempView=(ContactsListViewItemViews) view.getTag();
			
	        if(contact.getSimType() == 1){
	        	tempView.photoView.setBackgroundResource(R.drawable.sim1);
	        }else if(contact.getSimType() == 2){
	        	tempView.photoView.setBackgroundResource(R.drawable.sim2);
	        }else{
	        	tempView.photoView.setBackgroundResource(R.drawable.ic_contact_list_picture);
	        }
	        
			//tempView.photoView.setImageBitmap(contact.getPhoto());
			tempView.nameView.setText(contact.getName());
			tempView.numberView.setText(ContactsDBUtils.getPhoneText(contact.getPhone()));
			tempView.addressView.setText(contact.getName());
			tempView.addressView.setTag(new Boolean(true));  //if it is the ContactItem  or CallLogItem
			return view;
		}
		
		private View getContentView(){
			View view=mLayoutInflater.inflate(R.layout.twelve_key_dialer_listitem, null);
			ContactsListViewItemViews tempView=new ContactsListViewItemViews();
			tempView.photoView=(ImageView) view.findViewById(R.id.photoIv);
			tempView.nameView=(TextView) view.findViewById(R.id.nameTv);
			tempView.numberView=(TextView) view.findViewById(R.id.numberTv);
			tempView.addressView=(TextView) view.findViewById(R.id.addressTv);
			view.setTag(tempView);
			return view;
		}
		private View getDivideView(int strResId){
			View view=mLayoutInflater.inflate(R.layout.twelve_key_dialer_divideitem, null);
			TextView divideTitleTv = (TextView) view.findViewById(R.id.divideTitleTv);
			divideTitleTv.setText(strResId);
			return view;
		}
		
    }
    
    final class ContactsAdapter extends ResourceCursorAdapter {

        private CharSequence[] mLabelArray;

        private OnClickListener mAddListener = new OnClickListener() {
            public void onClick(View v) {
                String number = (String)v.getTag();
                Intent intent = new Intent("com.android.contacts.action.SHOW_OR_CREATE_CONTACT");
                intent.setData(Uri.fromParts("tel", number, null));
                startActivity(intent);
            }
        };

        private OnClickListener mAddListenerPeople = new OnClickListener() {
            public void onClick(View v) {
                String peopleId = (String)v.getTag();
                Log.v(TAG, "people id = " + peopleId);
                Intent intent = new Intent(Intent.ACTION_VIEW,
                            ContentUris.withAppendedId(Contacts.CONTENT_URI, Integer.valueOf(peopleId)));
                startActivity(intent);
            }
        };
        
        public ContactsAdapter() {
            super(CopyOfTwelveKeyDialer1.this, R.layout.twelve_key_dialer_list_item, null);
//            mLabelArray = getResources().getTextArray(com.android.internal.R.array.phoneTypes);
        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            View view = super.newView(context, cursor, parent);
            
            // Get the views to bind to
            ContactsListItemViews views = new ContactsListItemViews();
            views.line1View = (TextView) view.findViewById(R.id.line1);
            views.labelView = (TextView) view.findViewById(R.id.label);
            views.numberView = (TextView) view.findViewById(R.id.number);
            views.photoView = (ImageView) view.findViewById(R.id.photo);
            views.operateButton = (ImageView) view.findViewById(R.id.item_button);
            
            view.setTag(views);
            return view;
        }

        @Override
        public void bindView(View view, Context context, Cursor c) {
            final ContactsListItemViews views = (ContactsListItemViews) view.getTag();
            views.line1View.setText("");
            views.labelView.setText("");
            views.numberView.setText("");
            
            views.labelView.setVisibility(View.VISIBLE);
            views.labelView.setText(String.valueOf(c.getCount()));
            
/*         
            int id = c.getInt(ID_COLUMN_INDEX);
            String number = c.getString(NUMBER_COLUMN_INDEX);
            String formattedNumber = formatPhoneNumber(number);
            formattedNumber = formattedNumber.replace(',', 'p');
            formattedNumber = formattedNumber.replace(';', 'w');
            String callerName = c.getString(CALLER_NAME_COLUMN_INDEX);
            int callerNumberType = c.getInt(CALLER_NUMBERTYPE_COLUMN_INDEX);
            String callerNumberLabel = c.getString(CALLER_NUMBERLABEL_COLUMN_INDEX);
            Bitmap photo = null;
            int data = c.getInt(CALLER_PHOTO_INDEX);
            
//            photo =ContactsUtils.loadContactPhoto(context, data, null);
            
            //delete the title of seperator
//            View header = view.findViewById(R.id.header);
//            header.setVisibility(View.GONE);
            
            boolean isCalllog = id%2 == 0; 

            //delete the title of seperator
//            if(isCalllog && c.isFirst()){
//                header.setVisibility(View.VISIBLE);
//                TextView headerText = (TextView)header.findViewById(R.id.header_text);
//                headerText.setText(R.string.title_calllog);
//            }else if(!isCalllog && c.isFirst()){
//                header.setVisibility(View.VISIBLE);
//                TextView headerText = (TextView)header.findViewById(R.id.header_text);
//                headerText.setText(R.string.title_contacts);
//            }else if(!isCalllog){
//                c.moveToPrevious();
//                String provCallerName = c.getString(CALLER_NAME_COLUMN_INDEX);
//                if(TextUtils.isEmpty(provCallerName)){
//                    header.setVisibility(View.VISIBLE);
//                    TextView headerText = (TextView)header.findViewById(R.id.header_text);
//                    headerText.setText(R.string.title_contacts);                    
//                }
//                c.moveToNext();
//            }
            
            if(photo != null){
                views.photoView.setImageBitmap(photo);
            }else{
//                views.photoView.setImageResource(R.drawable.ic_contact_list_picture);
            }
            Integer dataId = c.getInt(CALLER_DATA_ID);
            Log.d(TAG, "CALLER_DATA_ID is >> " + dataId);
            views.photoView.setTag(dataId.toString());
            // Set the text lines
            if (!isCalllog) {
                if(!TextUtils.isEmpty(callerName)){
                    views.line1View.setText(callerName);
                    setEcho(c, views.line1View, 1);
                }else{
                    views.line1View.setText(formattedNumber);
                    setEcho(c, views.line1View, 0);
                }
                views.line1View.setTag(new Boolean(!isCalllog));
                views.labelView.setVisibility(View.VISIBLE);
                
                views.numberView.setVisibility(View.VISIBLE);
                views.numberView.setText(formattedNumber);
                setEcho(c, views.numberView, 0);
                
                Integer peopleId = c.getInt(CALLER_PEOPLE_ID);
                views.operateButton.setVisibility(View.VISIBLE);
                views.operateButton.setTag(peopleId.toString());
//                views.operateButton.setImageDrawable(getResources().getDrawable(R.drawable.btn_more));
                views.operateButton.setOnClickListener(mAddListenerPeople);
                
                CharSequence numberLabel = Phones.getDisplayLabel(context, callerNumberType, callerNumberLabel,
                        mLabelArray);
                
                if (!TextUtils.isEmpty(numberLabel)) {
                    views.labelView.setText(numberLabel);
                    views.labelView.setVisibility(View.VISIBLE);
                } else {
                    views.labelView.setVisibility(View.GONE);
                }
            } else {
                String voiceMailNumber = ((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE))
                .getVoiceMailNumber();
                
                views.operateButton.setVisibility(View.GONE);
                
                if (number.equals(CallerInfo.UNKNOWN_NUMBER)) {
                    number = getString(R.string.unknown);
                    views.line1View.setText(number);
                } else if (number.equals(CallerInfo.PRIVATE_NUMBER)) {
                    number = getString(R.string.private_num);
                    views.line1View.setText(number);
                } else if (number.equals(CallerInfo.PAYPHONE_NUMBER)) {
                    number = getString(R.string.payphone);
                    views.line1View.setText(number);
                } else if (number.equals(voiceMailNumber)) {
                    number = getString(R.string.voicemail);
                    views.line1View.setText(number);
                } else {
                    // Just a raw number, and no cache, so format it nicely
                    number = formatPhoneNumber(number);
                    views.operateButton.setVisibility(View.VISIBLE);
                    views.operateButton.setTag(number);
//                    views.operateButton.setImageDrawable(getResources().getDrawable(R.drawable.btn_add_more));
                    views.operateButton.setOnClickListener(mAddListener);
                    views.line1View.setText(formattedNumber);
                    setEcho(c, views.line1View, 0);
                }
                views.line1View.setTag(new Boolean(!isCalllog));
                
                views.numberView.setVisibility(View.GONE);
                views.labelView.setVisibility(View.GONE);
            }
*/        
        }
        
        private void setEcho(Cursor c, TextView text, int type){
            String inputNumber = mDigitsShow.getText().toString();
            if(TextUtils.isEmpty(inputNumber)){
                return;
            }

            String numberShort = c.getString(CALLER_NUMBER_SHORT_INDEX);
            String numberFull = c.getString(CALLER_NUMBER_FULL_INDEX);
            String indexShort = c.getString(CALLER_NUMBER_INDEX_SHORT_INDEX);
            String indexFull = c.getString(CALLER_NUMBER_INDEX_FULL_INDEX);
            
            //When index of pinyin is empty, echo by the rule of number. 
            if(TextUtils.isEmpty(numberShort) 
                    || TextUtils.isEmpty(numberFull)
                    || TextUtils.isEmpty(indexShort)
                    || TextUtils.isEmpty(indexShort)) {
                type = 0;
            }
            
            //echo the matched tel-number.
            if(type == 0){
                String number = text.getText().toString();
                int indexStart = number.indexOf(inputNumber);
                if(indexStart != -1){
                  StringBuilder echoText = new StringBuilder();
                  echoText.append(number.substring(0, indexStart));
                  echoText.append("<font color=\"#ff0000\">");
                  echoText.append(number.substring(indexStart, indexStart + inputNumber.length()));
                  echoText.append("</font>");
                  echoText.append(number.substring(indexStart + inputNumber.length(), number.length()));
                  text.setText(Html.fromHtml(echoText.toString()));
                  return;
                }

//                if(number.indexOf(inputNumber) == 0){
//                    StringBuilder echoText = new StringBuilder();
//                    echoText.append("<font color=\"#ff0000\">");
//                    echoText.append(number.substring(0, inputNumber.length()));
//                    echoText.append("</font>");
//                    echoText.append(number.substring(inputNumber.length(), number.length()));
//                    text.setText(Html.fromHtml(echoText.toString()));
//                    return;
//                }
            }else{
            //echo the matched name
                int indexStart = numberShort.indexOf(inputNumber);
                if(indexStart != -1){
                    String subIndex = indexShort.substring(indexStart, indexStart + inputNumber.length());
                    SetEchoWithIndex(subIndex, text);
                    return;
                }
                indexStart = numberFull.indexOf(inputNumber);
                if(indexStart != -1){
                    String subIndex = indexFull.substring(indexStart, indexStart + inputNumber.length());
                    SetEchoWithIndex(subIndex, text);
                    return;
                }
            }
        }
        
        private void SetEchoWithIndex(String index, TextView name){
            StringBuilder echoText = new StringBuilder();
            String text = name.getText().toString();
            for(int i = 0; i < text.length(); i++){
                if(index.contains(String.valueOf((char)('A' + i)))){
                    echoText.append("<font color=\"#ff0000\">");
                    echoText.append(text.charAt(i));
                    echoText.append("</font>");
                }else{
                    echoText.append(text.charAt(i));
                }
            }
            name.setText(Html.fromHtml(echoText.toString()));
        }
    }
    
    private static final class QueryHandler extends AsyncQueryHandler {
        private final WeakReference<CopyOfTwelveKeyDialer1> mActivity;

        /**
         * Simple handler that wraps background calls to catch
         * {@link SQLiteException}, such as when the disk is full.
         */
        protected class CatchingWorkerHandler extends AsyncQueryHandler.WorkerHandler {
            public CatchingWorkerHandler(Looper looper) {
                super(looper);
            }

            @Override
            public void handleMessage(Message msg) {
                try {
                    // Perform same query while catching any exceptions
                    super.handleMessage(msg);
                } catch (SQLiteDiskIOException e) {
                    Log.w(TAG, "Exception on background worker thread", e);
                } catch (SQLiteFullException e) {
                    Log.w(TAG, "Exception on background worker thread", e);
                } catch (SQLiteDatabaseCorruptException e) {
                    Log.w(TAG, "Exception on background worker thread", e);
                }
            }
        }

        @Override
        protected Handler createHandler(Looper looper) {
            // Provide our special handler that catches exceptions
            return new CatchingWorkerHandler(looper);
        }

        public QueryHandler(Context context) {
            super(context.getContentResolver());
            mActivity = new WeakReference<CopyOfTwelveKeyDialer1>(
                    (CopyOfTwelveKeyDialer1) context);
        }

        @Override
        protected void onQueryComplete(int token, Object cookie, Cursor cursor) {

            final CopyOfTwelveKeyDialer1 activity = mActivity.get();
            if (activity != null && !activity.isFinishing()) {
                final CopyOfTwelveKeyDialer1.ContactsAdapter callsAdapter = activity.mAdapter;
                callsAdapter.changeCursor(cursor);
                if(cursor==null||cursor.getCount()<1){
                	Message message = activity.mHandler.obtainMessage(activity.NO_CALLLOG_AND_CONTACTS);
                	message.sendToTarget();
                }else{
                	Message message = activity.mHandler.obtainMessage(activity.HAVE_CALLLOG_AND_CONTACTS);
                	message.sendToTarget();
                }
            } else {
            	if (null != cursor) cursor.close();
            }
        }
    }    


    /**
     * @return true if the phone is a CDMA phone type
     */
//    private boolean phoneIsCdma() {
//        boolean isCdma = false;
//        try {
//            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
//            if (phone != null) {
//                isCdma = (phone.getActivePhoneType() == TelephonyManager.PHONE_TYPE_CDMA);
//            }
//        } catch (RemoteException e) {
//            Log.w(TAG, "phone.getActivePhoneType() failed", e);
//        }
//        return isCdma;
//    }

//    /**
//     * @return true if the phone state is OFFHOOK
//     */
//    private boolean phoneIsOffhook() {
//        boolean phoneOffhook = false;
//        try {
//            ITelephony phone = ITelephony.Stub.asInterface(ServiceManager.checkService("phone"));
//            if (phone != null) phoneOffhook = phone.isOffhook();
//        } catch (RemoteException e) {
//            Log.w(TAG, "phone.isOffhook() failed", e);
//        }
//        return phoneOffhook;
//    }

    /**
     * Triggers haptic feedback (if enabled) for dialer key presses.
     */
//    private synchronized void vibrate() {
//        if (!mVibrateOn) {
//            return;
//        }
//        if (mVibrator == null) {
//            mVibrator = new Vibrator();
//        }
//        mVibrator.vibrate(mVibratePattern, VIBRATE_NO_REPEAT);
//    }

   
    /**
     * Initialize the vibration parameters.
     * @param r The Resources with the vibration parameters.
     */
//    private void initVibrationPattern(Resources r) {
//        int[] pattern = null;
//        try {
//            mVibrateOn = r.getBoolean(R.bool.config_enable_dialer_key_vibration);
//            pattern = r.getIntArray(com.android.internal.R.array.config_virtualKeyVibePattern);
//            if (null == pattern) {
//                Log.e(TAG, "Vibrate pattern is null.");
//                mVibrateOn = false;
//            }
//        } catch (Resources.NotFoundException nfe) {
//            Log.e(TAG, "Vibrate control bool or pattern missing.", nfe);
//            mVibrateOn = false;
//        }
//
//        if (!mVibrateOn) {
//            return;
//        }
//
//        // int[] to long[] conversion.
//        mVibratePattern = new long[pattern.length];
//        for (int i = 0; i < pattern.length; i++) {
//            mVibratePattern[i] = pattern[i];
//        }
//    }

    /**
     * This function return true if Wait menu item can be shown
     * otherwise returns false. Assumes the passed string is non-empty
     * and the 0th index check is not required.
     */
    private boolean showWait(int start, int end, String digits) {
        if (start == end) {
            // visible false in this case
            if (start > digits.length()) return false;

            // preceding char is ';', so visible should be false
            if (digits.charAt(start-1) == ';') return false;

            // next char is ';', so visible should be false
            if ((digits.length() > start) && (digits.charAt(start) == ';')) return false;
        } else {
            // visible false in this case
            if (start > digits.length() || end > digits.length()) return false;

            // In this case we need to just check for ';' preceding to start
            // or next to end
            if (digits.charAt(start-1) == ';') return false;
        }
        return true;
    }
    
}
